/*
 * Copyright (c) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef TIMELINE_RDB_MANAGER_H
#define TIMELINE_RDB_MANAGER_H

#include <string>
#include <memory>
#include <vector>
#include <thread>
#include <map>
#include <errors.h>
#include <mutex>
#include "rdb_store.h"
#include "rdb_helper.h"
#include "rdb_open_callback.h"
#include "rdb_store_config.h"
#include "values_bucket.h"
#include "result_set.h"
#include "timeline_data_utils.h"
#include "timeline_database_info.h"
#include "timeline_interface.h"
#include "timeline_common.h"
// #include "timeline_rdb_stay.h"

namespace OHOS {
namespace Msdp {
class TimelineService;
class TimelineRdbManager {
public:
	// explicit TimelineRdbManager(const wptr<TimelineService>& ms) : ms_(ms)
	// 	{
	// 		TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "TimelineManager instance is created.");
	// 	}
	// 	~TimelineRdbManager() = default;
    const int SLEEP_TIME = 21;
	const int WAKEUP_TIME = 6;
	TimelineDatabaseInfo::ListData listData;
	std::mutex mutex_;
    enum EventType {
		EVENT_UEVENT_FD,
		EVENT_TIMER_FD,
    };
    using CallbackImpl = std::function<int32_t(TimelineDataUtils::TimelineData&)>;
	using TimelineDatabaseMap = std::map<int, TimelineDatabaseInfo::ListData>;
	using MovementDataMap = std::map<int, TimelineDatabaseInfo::MovementData>;
public:
    bool Init();
    void InitRdbStore();
	void InitListRdbStore();
	void InitScheduleRdbStore();
    int32_t ScheduleRdbdataInsert(TimelineDatabaseInfo::MovementData& movementData);
	int32_t ListRdbdataInsert(TimelineDatabaseInfo::Schedule& schedule, int valuesUpdateFlag_);
    //void SetTimerInterval(int interval);
    //void SetTimerInterval(int interval);
    void InitAwakeTimer();
    void InitInactiveTimer();
    void InitSleepTimer();
    void SetTimerInterval(int interval);
    void AwakeTimerCallback();
    void InactiveTimerCallback();
    void SleepTimerCallback();
    void TimerCallback();
    int RegisterTimerCallback(const int fd, const EventType et);
    void StartThread();
    void LoopingThreadEntry();
    ErrCode Register(CallbackImpl callback);
    ErrCode Unregister() const;
    ErrCode NotifyMsdpImpl(TimelineDataUtils::TimelineData& data);
    int TrigerDatabaseObserver();
    TimelineDatabaseInfo::MovementData SaveRdbData(TimelineDatabaseInfo::MovementData& MovementData);
    bool UpdateSleepTime(int32_t sleeptime, int32_t wakeuptime);
	uint32_t GetSleepTime();
    uint32_t GetWakeupTime();
    ErrCode Enable();
    ErrCode Disable();
    TimelineDatabaseInfo::MovementData lbsData;
    int TrigerListDatabaseObserver();
	TimelineDatabaseInfo::ListData SaveListData(TimelineDatabaseInfo::ListData& listData);
	TimelineDatabaseInfo::MovementData movementData;
	TimelineDatabaseInfo::MovementData movementTempDataOne;
	TimelineDatabaseInfo::MovementData movementTempDataTwo;
	TimelineDatabaseInfo::Schedule scheduleTempOne;
	TimelineDatabaseInfo::Schedule scheduleTempTwo;
	TimelineDatabaseInfo::Schedule scheduleTempThree;
	void GetListMap(TimelineDatabaseMap &dataListMap);
  	void GetRdbMap(MovementDataMap &movementDataMap);
    int DeleteListDatabase(std::string tableName);
    int GetTimeDiff(tm &startTime, tm &endTime);
private: 
    using Callback = std::function<void(TimelineRdbManager*)>;
    CallbackImpl callbacksImpl_;
    std::map<int32_t, Callback> callbacks_;
    std::shared_ptr<NativeRdb::RdbStore> store_;
	std::shared_ptr<NativeRdb::RdbStore> scheduleStore_;
	std::shared_ptr<NativeRdb::RdbStore> listStore_;
	std ::shared_ptr<TimelineDatabaseInfo> timelinedatabaseinfo_;
	// const wptr<TimelineService> ms_;
	int timerInterval_ = -1;
	int32_t awakeTimerFd_ = -1;
	int32_t inactiveTimerFd_ = -1;
	int32_t sleepTimerFd_ = -1;
	int32_t epFd_ = -1;
	// int epollInterval_ = -1;
	int MovementType_ = -1;
	int MovementStatus_ = -1; 
    int DevicestatusType_ = -1;
	int TimeStamp_ = -1;
	double  Longitude_ = -1; 
	double  Latitude_ = -1; 
	std::string SSID_;
    std::string BSSID_;
	// struct tm time;
	int32_t sleeptime_ {22};
    int32_t wakeuptime_ {6};
	double latitude_;
	double longitude_;
	int32_t startTimeYear_;
	int32_t startTimeMonth_;
	int32_t startTimeDay_;
	int32_t startTimeHour_;
	int32_t startTimeMin_;
	int32_t startTimeSec_;
	int32_t endTimeYear_;
	int32_t endTimeMonth_;
	int32_t endTimeDay_;
	int32_t endTimeHour_;
	int32_t endTimeMin_;
	int32_t endTimeSec_;
	std::string listssid_;
    std::string listbssid_;
	int rdbId {0};
    int listId {0};
	MovementDataMap rdbDataMap_;
	TimelineDatabaseMap listDataMap_;
    int valuesUpdateFlag_ {0};
    // int scheduleValuesIDPutFlag_ {0};
    // double stayValuesUpdateMoment {-1};
};

class InsertOpenCallback : public NativeRdb::RdbOpenCallback {
public:
    int OnCreate(NativeRdb::RdbStore &rdbStore) override;
    int OnUpgrade(NativeRdb::RdbStore &rdbStore, int oldVersion, int newVersion) override;
};
}
}

#endif // TIMELINE_RDB_MANAGER_H